package com.joysuch.wwyt.workflow.utils;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonSyntaxException;
import com.joysuch.wwyt.bp.entity.BpSystemVideo;
import com.joysuch.wwyt.bp.repository.BpSystemVideoDao;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.common.util.JsonUtil;
import com.joysuch.wwyt.risk.entity.RiskDistrict;
import com.joysuch.wwyt.risk.repository.RiskDistrictDao;
import com.joysuch.wwyt.risk.service.RiskDistrictService;
import com.joysuch.wwyt.workflow.WorkFlowConstants;
import com.joysuch.wwyt.workflow.bean.*;
import com.joysuch.wwyt.workflow.enums.WorkFlowFiledTypeEnum;
import com.joysuch.wwyt.workflow.service.WorkFlowTaskHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Author:  feizhou
 * Date:    2022/9/27 17:10
 */
@Slf4j
public class FormComponentUtil {

    public static FormTableData parseTableData(String key, JSONObject formData, List<ComponentFormColumn> tableHeaders, String processFormJson, String taskCode) {
        FormTableData formTableData = emptyFormTableData();
        if (tableHeaders == null) {
            tableHeaders = new ArrayList<>(0);
        }
        tableHeaders.forEach(header -> {
            if (header.getProp() == null) {
                header.setProp(header.getLabel());
            }
        });
        formTableData.setTableHeaders(tableHeaders);
        if (formData == null || StringUtils.isEmpty(key)) {
            return formTableData;
        }
        JSONArray jsonArray = formData.getJSONArray(key);
        if (jsonArray == null) {
            return formTableData;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject rowData = new JSONObject();
            JSONObject rowTempData = jsonArray.getJSONObject(i);

            for (ComponentFormColumn col : tableHeaders) {
//                String value = "";
//                String type = col.getType();
//                Object v = rowTempData.get(col.getLabel());
//                if (v instanceof String) {
//                    rowData.put(col.getLabel(), v);
//                    continue;
//                }
//                if (WorkFlowFiledTypeEnum.target.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.targets.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.select.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.radio.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.checkbox.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.video.getType().equals(type)
//                        || WorkFlowFiledTypeEnum.monitorpoint.getType().equals(type)
//                ) {
//                    JSONArray arr = rowTempData.getJSONArray(col.getLabel());
//                    List<String> list = Lists.newArrayList();
//                    if (arr != null) {
//                        for (int j = 0; j < arr.size(); j++) {
//                            JSONObject labelObj = arr.getJSONObject(j);
//                            String label = labelObj.getString("label");
//                            if (label != null) {
//                                list.add(label);
//                            }
//                        }
//                    }
//                    value = list.stream().collect(Collectors.joining(","));
//                } else if (WorkFlowFiledTypeEnum.signature.getType().equals(type)) {
//                    JSONObject signatureObj = rowTempData.getJSONObject(col.getLabel());
//                    JSONArray signatureList = new JSONArray();
//                    if (signatureObj != null) {
//                        JSONArray array = signatureObj.getJSONArray("operator_signature");
//                        if (array != null) {
//                            for (int k = 0; k < array.size(); k++) {
//                                JSONObject obj = array.getJSONObject(k);
//                                String imgUrl = obj.getString("imgUrl");
//                                if (StringUtils.isNotEmpty(imgUrl)) {
//                                    int idIndex = imgUrl.indexOf("id");
//                                    if (idIndex != -1) {
//                                        String substring = imgUrl.substring(idIndex);
//                                        JSONObject newObj = new JSONObject();
//                                        newObj.put("imgUrl",  "?" + substring);
//                                        signatureList.add(newObj);
//                                    }
//                                }
//                            }
//                        }
//                    }
//                    value = signatureList.toJSONString();
//                } else {
//                    value = rowTempData.getString(col.getLabel());
//                }
                ComponentFormColumn formColumn = getValue(col.getProp(), col.getLabel(), col.getType(), rowTempData, processFormJson, taskCode);
                formColumn.setLabel(col.getLabel());
                formColumn.setProp(col.getProp());
                if (StringUtils.isEmpty(formColumn.getProp())) {
                    formColumn.setProp(col.getLabel());
                }
                rowData.put(col.getLabel(), formColumn.getValue());
            }
            formTableData.getTableRows().add(rowData);
        }


        return formTableData;
    }


    private static FormTableData emptyFormTableData() {
        FormTableData tableData = new FormTableData();
        List<ComponentFormColumn> tableHeaders = Lists.newArrayList();
        tableData.setTableRows(new JSONArray());
        tableData.setTableHeaders(tableHeaders);
        return tableData;
    }

    public static List<ComponentFormColumn> parseData(List<WorkFlowScreenConfigBean.DetailColumn> detailColumns, JSONObject formData, String processFormJson, String taskCode) {
        List<ComponentFormColumn> componentFormColumns = Lists.newArrayList();
        if (detailColumns == null) {
            return componentFormColumns;
        }

        List<ComponentFormColumn> formColumnList = Lists.newArrayList();
        for (WorkFlowScreenConfigBean.DetailColumn detailColumn : detailColumns) {
            if ("table".equals(detailColumn.getType())) {
                ComponentFormColumn groupColumn = new ComponentFormColumn();
                groupColumn.setLabel(detailColumn.getLabel());
                groupColumn.setProp(detailColumn.getKey());
                groupColumn.setType("group");

                ComponentFormColumn column = new ComponentFormColumn();
                column.setLabel(detailColumn.getLabel());
                column.setProp(detailColumn.getKey());
                column.setType("dynamic");

                ComponentFormColumn children = new ComponentFormColumn();
                children.setLabel(detailColumn.getLabel());
                children.setProp(detailColumn.getKey());
                children.setType("");
                List<ComponentFormColumn> childrenColumn = Lists.newArrayList();
                if (detailColumn.getSelectArr() != null) {
                    for (WorkFlowScreenConfigBean.SelectArr select : detailColumn.getSelectArr()) {
                        ComponentFormColumn formColumn = new ComponentFormColumn();
                        formColumn.setType(select.getType());
                        formColumn.setLabel(select.getLabel());
                        formColumn.setProp(select.getKey());
                        if (StringUtils.isEmpty(formColumn.getProp())) {
                            formColumn.setProp(select.getLabel());
                        }
                        childrenColumn.add(formColumn);
                    }
                }

                children.setColumn(childrenColumn);
                column.setChildren(children);

                column.setTableRows(parseTableData(detailColumn, formData, processFormJson, taskCode));
                List<ComponentFormColumn> columns = Lists.newArrayList();
                columns.add(column);
                groupColumn.setColumn(columns);
                formColumnList.add(groupColumn);
//            } else if (StringUtils.isEmpty(detailColumn.getType()) || "group".equals(detailColumn.getType())) {
            } else {
                List<WorkFlowScreenConfigBean.SelectArr> selectArr = detailColumn.getSelectArr();
                ComponentFormColumn column = new ComponentFormColumn();
                column.setLabel(detailColumn.getLabel());
                column.setProp(detailColumn.getKey());
                column.setType("group");
                List<ComponentFormColumn> subFormColumnList = Lists.newArrayList();
                if (selectArr != null) {
                    for (WorkFlowScreenConfigBean.SelectArr select : selectArr) {

                        ComponentFormColumn subCol = getValue(select.getLabel(), select.getKey(), select.getType(), formData, processFormJson, taskCode);
                        subFormColumnList.add(subCol);
                    }
                }
                column.setColumn(subFormColumnList);
                formColumnList.add(column);
            }
        }

        return formColumnList;
    }

    private static ComponentFormColumn getValue(String label, String key, String type, JSONObject formData, String processFormJson, String taskCode) {
        ComponentFormColumn subCol = new ComponentFormColumn();
        subCol.setType(type);
        String value = "";
        if (StringUtils.isNotEmpty(key)) {
            if (WorkFlowFiledTypeEnum.signature.getType().equals(type)) {
                try {
                    JSONObject signatureObj = formData.getJSONObject(key);
                    JSONArray signatureList = new JSONArray();
                    if (signatureObj != null) {
                        JSONArray array = signatureObj.getJSONArray("operator_signature");
                        if (array != null) {
                            for (int k = 0; k < array.size(); k++) {
                                JSONObject obj = array.getJSONObject(k);
                                String imgUrl = obj.getString("imgUrl");
                                if (StringUtils.isNotEmpty(imgUrl)) {
                                    int idIndex = imgUrl.indexOf("id");
                                    if (idIndex != -1) {
                                        String substring = imgUrl.substring(idIndex);
                                        JSONObject newObj = new JSONObject();
                                        newObj.put("imgUrl",  "?" + substring);
                                        signatureList.add(newObj);
                                    }
                                }
                            }
                        }
                    }
                    value = signatureList.toJSONString();
                } catch (Exception e) {
                    log.error("parse signature error", e);
                }
            }   else if ("annex".equals(type)) {
                JSONArray newArr = new JSONArray();
                try {
                    JSONArray jsonArray = formData.getJSONArray(key);
                    if (jsonArray != null) {
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject obj = jsonArray.getJSONObject(i);
                            if (obj != null) {
                                String name = obj.getString("name");
                                Long id = obj.getLong("id");
                                JSONObject objNew = new JSONObject();
                                objNew.put("name", name);
                                objNew.put("fileUrl", "?id=" + id);
                                newArr.add(objNew);
//                                value = objNew.toJSONString();
                            }
                        }
                    }

                } catch (Exception e) {
                    try {
                        JSONObject obj = formData.getJSONObject(key);
                        if (obj != null) {
                            String name = obj.getString("name");
                            Long id = obj.getLong("id");
                            JSONObject objNew = new JSONObject();
                            objNew.put("name", name);
                            objNew.put("fileUrl", "?id=" + id);
                            newArr.add(objNew);
                        }
                    } catch (Exception exception) {
                        log.error("parse annex error", e);
                    }
                    log.error("parse annex error", e);
                }
                value = newArr.toJSONString();
            }  else if ("annexes".equals(type)) {
                try {
                    String string = formData.getString(key);
                    if (StringUtils.isNotEmpty(string)) {

                        JSONArray array = JSONArray.parseArray(string);
                        JSONArray arrayNew = new JSONArray();
                        if (array != null) {
                            for (int i = 0; i < array.size(); i++) {
                                JSONObject obj = array.getJSONObject(i);
                                String name = obj.getString("name");
                                Long id = obj.getLong("id");
                                JSONObject objNew = new JSONObject();
                                objNew.put("name", name);
                                objNew.put("fileUrl", "?id=" + id);
                                arrayNew.add(objNew);
                            }
                        }
                        value = arrayNew.toJSONString();
                    }
                } catch (Exception e) {
                    log.error("parse annexes error", e);
                }
            } else if ("checkbox".equals(type)) {
                try {
                    String val = formData.getString(key);
                    if (val != null) {
                        List<String> list = JsonUtil.fromListJson(val, String.class);
                        if (list != null) {
                            value = list.stream().collect(Collectors.joining(","));
                        }
                    }
                } catch (Exception e) {
                    log.error("parse checkbox error ",  e);
                }
            } else if ("picture".equals(type)) {
                try {
                    String val = formData.getString(key);
                    JSONArray array = new JSONArray();
                    if (val != null) {
                        List<String> list = JsonUtil.fromListJson(val, String.class);
                        if (list != null) {
                            list.forEach(fileUrl -> {
                                int i = fileUrl.indexOf("?id");
                                if (i == -1) {
                                    return;
                                }
                                String substring = fileUrl.substring(i);
                                JSONObject obj = new JSONObject();
                                obj.put("fileUrl", substring);
                                array.add(obj);
                            });
                        }
                        value = array.toJSONString();
                    }
                    subCol.setValue(value);
                    subCol.setType("picture");
                } catch (Exception e) {
                    log.error("parse picture error ", e);
                }
            } else if ("video".equals(type)) {
                try {
                    JSONObject obj = formData.getJSONObject(key);
                    if (obj != null) {
                        value = obj.toJSONString();
                    }
                } catch (Exception e) {
                    log.error("parse video error ", e);
                }
            } else if ("videoSurveillance".equals(type)) {
                try {
                    JSONObject obj = formData.getJSONObject(key);
                    if (obj != null) {
                        Long id = obj.getLong("id");
                        BpSystemVideoDao bpSystemVideoDao = com.joysuch.wwyt.util.ApplicationContextHolder.getBean(BpSystemVideoDao.class);
                        Optional<BpSystemVideo> op = bpSystemVideoDao.findById(id);
                        if (op.isPresent()) {
                            obj.put("historySite", op.get().getHistorySite());
                            obj.put("dateFormat", op.get().getDateFormat());
                            obj.put("timeFormat", op.get().getTimeFormat());
                        }
                        value = obj.toJSONString();
                        JSONObject resultObj = JSONObject.parseObject(value);
                        String startTime = getVideoStartTimeFrom(processFormJson, key, "startTime");
                        String endTime = getVideoStartTimeFrom(processFormJson, key, "endTime");
                        if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                            WorkFlowTaskHistoryService workFlowTaskHistoryService = com.joysuch.wwyt.util.ApplicationContextHolder.getBean(WorkFlowTaskHistoryService.class);
                            WorkFlowSubmitTimeBean timeBean = new WorkFlowSubmitTimeBean();
                            timeBean.setType(2);
                            timeBean.setProcessStartName(startTime);
                            timeBean.setProcessEndName(endTime);
                            timeBean.setTaskCode(taskCode);
                            WorkFlowTimeSliceBean processTimePeriod = workFlowTaskHistoryService.getProcessTimePeriod(timeBean);
                            resultObj.put("canDisplay", true);
                            resultObj.put("taskCode", taskCode);
                            if (processTimePeriod != null) {
                                if (processTimePeriod.getStartTime() != null) {
                                    resultObj.put("startTime", DateTimeUtil.formatDate(processTimePeriod.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
                                } else {
                                    resultObj.put("canDisplay", false);
                                }
                                if (processTimePeriod.getEndTime() != null) {
                                    resultObj.put("endTime", DateTimeUtil.formatDate(processTimePeriod.getEndTime(), "yyyy-MM-dd HH:mm:ss"));
                                    if ((processTimePeriod.getSelectEnd() != null && processTimePeriod.getSelectEnd()) || (processTimePeriod.getProcessEnd() != null && processTimePeriod.getProcessEnd())) {
                                        resultObj.put("isHistory", true);
                                    } else {
                                        resultObj.put("isHistory", false);
                                    }
                                } else {
                                    resultObj.put("isHistory", false);
                                }
                                if (processTimePeriod.getTipMessage() != null) {
                                    resultObj.put("tipMessage", processTimePeriod.getTipMessage());
                                }
                            } else {
                                resultObj.put("canDisplay", false);
                            }
                            value = resultObj.toJSONString();
                        }
                    }
                } catch (Exception e) {
                    log.error("parse video error ", e);
                }
            }  else if ("riskAssessment".equals(type)) {
                try {
                    String val = formData.getString(key);
                    if (val.contains("riskDistrictId")) {
                        JSONObject district = JSONObject.parseObject(val);
                        if (district != null) {
                            Long id = district.getLong("riskDistrictId");
                            if (id != null) {
                                subCol.setType("input");
                                try {
                                    RiskDistrictService districtService = com.joysuch.wwyt.util.ApplicationContextHolder.getBean(RiskDistrictService.class);
                                    RiskDistrict riskDistrict = districtService.findById(id);
                                    if (riskDistrict != null) {
                                        subCol.setValue(riskDistrict.getName());
                                        return subCol;
                                    }
                                } catch (Exception e) {
                                    log.error("find risk district error", e);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("parse riskAssessment error ", e);
                }
            }
            else {
                try {
                    String val = formData.getString(key);
                    if (val != null) {
                        if ("dialog".equals(type)) {
                            if (val.contains("[") && val.contains("]") && val.contains("{")) {
                                JSONArray array = JSONArray.parseArray(val);
                                JSONArray arrayNew = new JSONArray();
                                List<String> list = Lists.newArrayList();
                                if (array != null) {
                                    for (int i = 0; i < array.size(); i++) {
                                        JSONObject obj = array.getJSONObject(i);
                                        String myLabel = obj.getString("label");
                                        list.add(myLabel);
                                    }
                                }
                                value = list.stream().collect(Collectors.joining(","));
                                subCol.setType("input");
                            } else {
                                value = val;
                                subCol.setType("input");
                            }
                        } else {
                            value = val;
                        }
                    }
                } catch (Exception e) {
                    log.error("parse other error ", e);
                }
            }
        }

        subCol.setLabel(label);
        subCol.setValue(value);
        subCol.setProp(key);
        return subCol;
    }

    private static String getVideoStartTimeFrom(String fromJsonStr, String key, String targetKey) {
        if (StringUtils.isNotBlank(fromJsonStr)) {
            JSONObject fromJson = JSON.parseObject(fromJsonStr);
            Object temArrObj = fromJson.get(WorkFlowConstants.FROM_JSON_KEY_TEMARR);
            if (temArrObj != null) {
                JSONArray temArr = JSONObject.parseArray(temArrObj.toString());
                for (Object tem : temArr) {
                    Map<String, Object> tableMap = JSONObject.parseObject(JSON.toJSONString(tem));
                    Object tableArrObj = tableMap.get(WorkFlowConstants.FROM_JSON_KEY_TABLEARR);
                    JSONArray tableArr = JSONObject.parseArray(tableArrObj.toString());
                    for (Object table : tableArr) {
                        Map<String, Object> beanMap = JSONObject.parseObject(JSON.toJSONString(table));
                        Object keyObj = beanMap.get(WorkFlowConstants.FROM_JSON_KEY_SELF);
                        if (keyObj != null) {
                            String value = (String) keyObj;
                            if (value.equals(key)) {
                                Object specialObj = beanMap.get(WorkFlowConstants.FROM_JSON_KEY_SPECIAL);
                                if (specialObj != null) {
                                    JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(specialObj));
                                    JSONObject video = jsonObject.getJSONObject("video");
                                    if (video != null) {
                                        return video.getString(targetKey);
                                    }
                                }

                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    private static JSONArray parseTableData(WorkFlowScreenConfigBean.DetailColumn detailColumn, JSONObject formData, String processFormJson, String taskCode) {
        List<ComponentFormColumn> tableHeaders = Lists.newArrayList();
        if (detailColumn.getSelectArr() != null) {
            for (WorkFlowScreenConfigBean.SelectArr select : detailColumn.getSelectArr()) {
                ComponentFormColumn formColumn = new ComponentFormColumn();
                formColumn.setType(select.getType());
                formColumn.setLabel(select.getLabel());
                formColumn.setProp(select.getKey());
                if (StringUtils.isEmpty(formColumn.getProp())) {
                    formColumn.setProp(formColumn.getLabel());
                }
                tableHeaders.add(formColumn);
            }
        }
        FormTableData formTableData = parseTableData(detailColumn.getKey(), formData, tableHeaders, processFormJson, taskCode);
        return formTableData.getTableRows();
    }

}
